import { siteStorageKey } from '@/config/settings';
class Storage {
  constructor() {
    this.storageName = siteStorageKey || 'expiredStorage';
  }

  /**
   * 设置缓存
   * @param {string} name 缓存名称
   * @param {any} value 缓存的值
   * @param {number} expires 缓存过期时间(秒)
   */
  set(name, value, expires) {
    // 优化：只在必要时才进行反序列化和序列化操作
    let storages = this.getStorages();

    const expiresAt =
      expires === undefined
        ? +new Date() + 31536000000 // 默认365天
        : expires * 1000 + +new Date();

    storages[name] = {
      value,
      expires: expiresAt,
    };
    localStorage.setItem(this.storageName, JSON.stringify(storages));
  }

  /**
   * 获取缓存
   * @param {string} name 缓存名称
   * @return {any|null} 缓存的值或null（如果不存在或已过期）
   */
  get(name) {
    let storages = this.getStorages();
    try {
      // 不存在
      if (!storages[name]) return null;

      if (+new Date() > storages[name].expires) {
        // 存在但过期
        this.remove(name);
        return null;
      }
      return storages[name].value;
    } catch (error) {
      console.log(
        '[ControlStorage] the error message: get field failed\n',
        error,
      );
      return null;
    }
  }

  /**
   * 移除对应缓存
   * @param {string} name 缓存名称
   */
  remove(name) {
    let storages = this.getStorages();
    try {
      delete storages[name];
      if (JSON.stringify(storages) === '{}') {
        // 缓存字段为空对象时，删除该字段
        this.clear();
        return;
      }
      this.updateStorages(storages);
    } catch (error) {
      console.log(
        '[ControlStorage] the error message: remove field failed\n',
        error,
      );
    }
  }

  /**
   * 清除所有带过期时间的缓存
   */
  clear() {
    localStorage.removeItem(this.storageName);
  }

  /**
   * 辅助方法：从localStorage获取存储对象
   * @return {Object} 存储对象
   */
  getStorages() {
    const item = localStorage.getItem(this.storageName);
    return item ? JSON.parse(item) : {};
  }

  /**
   * 辅助方法：更新localStorage中的存储对象
   * @param {Object} storages 存储对象
   */
  updateStorages(storages) {
    localStorage.setItem(this.storageName, JSON.stringify(storages));
  }
}

export default new Storage();
